12. Exercise: Display an Internet Image
L8 19 Displaying An Internet Image HS-SC
Erratum
At timestamp 04:35 in the video above, inOverviewFragment.ktfile, insideonCreateView()function, the way to set the binding lifecycle to itself has changed frombinding.setLifecycleOwner(this)tobinding.lifecycleOwner = this.
Now it's your turn to complete this exercise yourself! At the end of this exercise you will have downloaded and displayed your very first image from Mars.
If you want to start at this step, you can download this exercise from: Step.04-Exercise-Displaying-an-Internet-Image. You will find plenty of //TODO comments to help you complete this exercise,
- In
build.gradle, add the Glide library dependency:
implementation "com.github.bumptech.glide:glide:$version_glide"
- In
OverViewViewModel, renameresponseLiveDatatostatus:
private val _status = MutableLiveData<String>()
val status: LiveData<String>
get() = _status
- Add an encapsulated
LiveData<MarsProperty>property:
private val _property = MutableLiveData<MarsProperty>()
val property: LiveData<MarsProperty>
get() = _property
- Update
getMarsRealEstateProperties()to set _property to the first MarsProperty from listResult:
if (listResult.size > 0) {
_property.value = listResult[0]
}
and the error response to a status value:
_status.value = "Failure: ${e.message}"
- In
fragment_overview.xmlchange theTextViewbinding toviewModel.property.imgSrcUrl.
android:text="@{viewModel.property.imgSrcUrl}"
Running the app now displays the Url to the first Mars image. Next, we'll load and display that image with Glide.
In
BindingAdapterscreate aBindingAdapterto convertimgUrlto aURIwith the https scheme.Inside the adapter, use
Glideto download the image display it inimgView:@BindingAdapter("imageUrl") fun bindImage(imgView: ImageView, imgUrl: String?) { imgUrl?.let { val imgUri = imgUrl.toUri().buildUpon().scheme("https").build() Glide.with(imgView.context) .load(imgUri) .into(imgView) } }In
grid_view_item.xml, add aviewModeldata variable.
<data>
<variable
name="viewModel"
type="com.example.android.marsrealestate.overview.OverviewViewModel" />
</data>
- Bind
mars_imageto the imageView using the recently addedimgUrlBindingAdapter.
app:imageUrl="@{viewModel.property.imgSrcUrl}"
- Back in
OverviewFragment, replaceFragmentOverviewBindingwithGridViewItemBinding.
val binding = GridViewItemBinding.inflate(inflater)
- Build and run your app. You should see a beautiful piece of property on Mars. Who wouldn't want to live there?
We can do one more thing to make this work even better. Currently our app doesn't display anything when we're loading, and if the loading fails there's no indication to the user.
- In
BindingAdapters, applyRequestOptionsto theGlidecall to add a placeholder that displays an image while your image downloads, and an error image in case it can't be retrieved.
.apply(RequestOptions()
.placeholder(R.drawable.loading_animation)
.error(R.drawable.ic_broken_image))
- Build and run your app. You might just catch a blink of the loading animation if you have a fast connection.
If you get stuck, go back and watch the video again. Once you’re done, you can check your solution against the solution we’ve provided here: Step.04-Solution-Displaying-an-Internet-Image, or using this git diff.
Task Description:
Complete the tasks below to display an image.
Task Feedback:
Good work! Are you ready to see some more Mars images?
Reference documentation